package com.pingan.haofang.searchcloud.monitor.dao;

import com.pingan.haofang.searchcloud.monitor.convert.ColumnToBean;
import org.hibernate.SQLQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.util.CollectionUtils;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

    /**
     * 获取列表（包括分页、条件查询）
     *
     * @param paramMap 查询条件参数 ，如果没查询参数，可以传null值
     * @param sql 要执行的本地SQL语句
     * @param page 分页信息
     * @param resultClass 分页结果集包装类
     * @return 分页结果数据
     */
    default <T> Page<T> getConditionPage(Map<String, Object> paramMap, String sql, Pageable page, Class<T> resultClass,
            EntityManager entityManager) {

        // 获取总记录数
        Query countQuery = entityManager.createNativeQuery("select count(*) from (" + sql + ") as p");

        // 获取分页结果
        Query pageQuery = entityManager.createNativeQuery(sql);

        if (!CollectionUtils.isEmpty(paramMap)) {
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                countQuery.setParameter(entry.getKey(), entry.getValue());
                pageQuery.setParameter(entry.getKey(), entry.getValue());
            }
        }
        int totalRecord = ((BigInteger) countQuery.getSingleResult()).intValue();
        List<T> datas = totalRecord == 0 ? new ArrayList<>(0)
                : pageQuery.setFirstResult(page.getOffset()).setMaxResults(page.getPageSize()).unwrap(SQLQuery.class)
                        .setResultTransformer(new ColumnToBean(resultClass)).list();
        return new PageImpl<>(datas, page, totalRecord);
    }

    /**
     * 获取列表
     */
    default <T> List<T> getConditionList(Map<String, Object> paramMap, String sql, Class<T> resultClass,
            EntityManager entityManager) {

        // 获取分页结果
        Query query = entityManager.createNativeQuery(sql);

        if (!CollectionUtils.isEmpty(paramMap)) {
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                query.setParameter(entry.getKey(), entry.getValue());
            }
        }
        List<T> datas = query.unwrap(SQLQuery.class).setResultTransformer(new ColumnToBean(resultClass)).list();
        return datas;
    }

}
